/*************************************************************************
    > File Name: server.c
    > Author: sun
    > Mail: sunhonghe123@qq.com
    > Created Time: 2024年06月16日 星期日 21时41分26秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include <errno.h>
#include <fcntl.h>

int main()
{
	//创立监听套接字
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("socket");
		exit(0);
	}
	//允许端口复用
	int opt = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) < 0)
	{
		perror("setsockpot");
		exit(0);
	}
	
	//绑定
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8080);
	addr.sin_addr.s_addr = INADDR_ANY;
	int ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
	if(ret == -1)
	{
		perror("bind");
		exit(0);
	}

	//设置监听
	ret = listen(sockfd, 128);
	if(ret == -1)
	{
		perror("listen");
		exit(0);
	}
	
	//初始化要检测的文件描述符集合
	fd_set readfds;
	FD_ZERO(&readfds);
	FD_SET(sockfd, &readfds);
	int nfds = sockfd;

	while(1)
	{
		/*fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(sockfd, &readfds);
		int nfds = sockfd;*/
		
		//使用select监控文件描述符
		int num = select(nfds + 1, &readfds, NULL, NULL, NULL);
		printf("num = %d\n", num);
		if(FD_ISSET(sockfd, &readfds))
		{
			struct sockaddr_in cliaddr;
			int clilen = sizeof(cliaddr);
			//建立新连接
			int newfd;
			if((newfd = accept(sockfd, (struct sockaddr*)&cliaddr, (socklen_t*)&clilen)) < 0)
			{
				perror("accept");
				continue;
			}

			//通信
			char buf[1024];
			memset(buf, 0, sizeof(buf));
			int valread = read(newfd, buf, sizeof(buf));
			if(valread == 0)
			{
				printf("客户端断开了连接...\n");
				FD_CLR(newfd, &readfds);
				close(newfd);
			}
			else if(valread > 0)
			{
				printf("接收的文件名：%s\n", buf);
			}
			else
			{
				perror("read");
			}

			//打开文件并发送内容
			int file_fd = open(buf, O_RDONLY);
			if (file_fd != -1)
			{
				char file_buf[1024];
				while((valread = read(file_fd, file_buf, sizeof(file_buf))) > 0)
				{
					send(newfd, file_buf, valread, 0);
				}
				close(file_fd);

			}
			else
			{
				send(newfd, "文件没有创建", 8, 0);
			}
			close(newfd);
		}

	}

	return 0;

}

